package com.tiny.tests;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import com.tiny.core.game.Game;
import com.tiny.core.game.GameObject;
import com.tiny.core.game.util.MovimentCalculator;
import com.tiny.core.graphics.camera.Camera2d;
import com.tiny.core.input.KeyboardManager;
import com.tiny.core.physics.CollisionDetector;
import com.tiny.core.physics.PhysicGameObject;
import com.tiny.core.physics.SimpleGravityManager;
import com.tiny.core.physics.Vector;
import com.tiny.tests.common.StaticWall;

public class Camera2dExample extends Game {

    private CollisionDetector collisor;
    private SimpleGravityManager gravityManager;
    private List<GameObject> objs;
    private Camera2d camera;
    private Player player;

    @Override
    public void onLoad() {
        player = new Player(10, -100, getMovimentCalculator());

        objs = new ArrayList<GameObject>();
        collisor = new CollisionDetector(objs);

        List<PhysicGameObject> physicGameObjects = new ArrayList<PhysicGameObject>();
        physicGameObjects.add(player);
        gravityManager = new SimpleGravityManager(physicGameObjects, 5d);
        objs.add(player);
        camera = new Camera2d(this, player);

        StaticWall last = null;
        for (int j = 1; j < 5; j++) {
            for (int i = 0; i < 10; i++) {
                last = new StaticWall(i * 200 + 5, getHeight() - (j * 150) - (i * 30), 150, 30);
                objs.add(last);
            }
        }
        Vector boundsX = new Vector(0, (int)(last.getPos().x + last.getPos().width));
        camera.setBoundsX(boundsX);
        camera.setBoundsY(new Double(getHeight()));

        camera.setObjectsToManage(objs);
    }

    @Override
    public void onUnload() {

    }

    @Override
    public void onUpdate(int currentTick) {
        gravityManager.update();
        collisor.update();
        for (GameObject o : objs) {
            o.update(currentTick);
        }

        if (KeyboardManager.getInstance().isHold(KeyEvent.VK_W)) {
            camera.zoom(0.01);
        }

        if (KeyboardManager.getInstance().isHold(KeyEvent.VK_S)) {
            camera.zoom(-0.01);
        }

        camera.update(currentTick);

        if (KeyboardManager.getInstance().isHold(KeyEvent.VK_ESCAPE)) {
            terminate();
        }
     //   System.out.println(camera);
    }

    @Override
    public void onRender(Graphics2D g) {
        Graphics2D g2d = (Graphics2D)g.create();
        camera.render(g2d);
        g.setColor(Color.WHITE);
        g.drawString("Rendering: " + camera.getObjectsToRender().size(), 10, 10);
        g2d.dispose();
    }

    @Override
    public String getTitle() {
        return "Camera Example";
    }

    public static void main(String[] args) {
        new Camera2dExample().run();
    }
}

class Player extends PhysicGameObject {

    public Player(int x, int y, MovimentCalculator calc) {
        super(x, y, 20, 50, calc);
    }

    @Override
    public void render(Graphics2D g) {
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect((int)pos.x, (int)pos.y, (int)pos.width, (int)pos.height);
        g.drawString("[X:" + pos.x + "|Y:" + pos.y + "]", (int)(pos.x + pos.width + 5), (int)(pos.y - 5));
    }

    @Override
    public void onUpdate(int currentFrame) {
        if (collidingEntities[COLLIDING_BELOW] != null) {
            setOnGround(true);
            fixCollidingPosition();
        } else {
            setOnGround(false);
        }

        if (KeyboardManager.getInstance().isHold(KeyEvent.VK_RIGHT) && !isCollingRight()) {
            getVelocity().setX(100);
        } else if (KeyboardManager.getInstance().isHold(KeyEvent.VK_LEFT) && !isCollingLeft()) {
            getVelocity().setX(-100);
        } else {
            getVelocity().setX(0);
        }

        if (KeyboardManager.getInstance().isPressed(KeyEvent.VK_SPACE) && isOnGround()) {
            getVelocity().setY(-200);
        }
    }
    
}